// 原始类型
let bool: boolean = true;
let num: number | undefined | null = 123;
let str: string = "abc";
// str = 123;

// 数组
let arr1: number[] = [1, 2, 3];
let arr2: Array<number> = [1, 2, 3];

// 数组—联合类型
let arr3: Array<number | string> = [1, 2, 3, '4'];


// 元组—是一种特殊的数组，它限定了数组元素的类型和个数
let tuple: [number, string] = [0, "1"]; // 第一位必须是 number
// let tuple1: [number, string] = ['0', 1, 2];
tuple.push(2); // 开发中不建议去操作元组
console.log(tuple); // 输出：[0, "1", 2] ts允许我们往元组中添加入新的元素的
// console.log(tuple[2]); // 不允许我们访问使用 push 添加进去的数据


// 函数
let add = (x: number, y: number): number => x + y;
let computed: (x: number, y: number) => number; // 函数类型
computed = (a, b) => a + b; // 在实际的实现过程中呢函数参数的名称可以和定义时不一样而且也不用指定具体的类型了

// 对象
let obj: object = {x: 1, y: 2};
// obj.x = 3; // 在js中呢我们可以任意的修改对象中的属性，在ts中这种操作是不允许的因为我们只是简单的指定了object类型是object并没有具体的定义它应该包含哪些属性
let obj1: {x: number, y: number} = {x: 1, y: 2};
obj1.x = 3; // 这样定义就可以修改属性的值了

// symbol【symbol的含义就是具有唯一的值】
let s1: symbol = Symbol();
let s2 = Symbol();
console.log(s1 === s2); // false

// undefined，null【我们可以给一个变量声明为undefined和null，但是如果声明了undefined它就不能赋值任何其它数据类型了】
let un: undefined = undefined;
// let un: undefined = 1; 不能赋值其它类型
let nu: null = null;

num = undefined;
num = null; // 不能将 undefined和null 赋值给 number，可以在 tsconfig.json 将`strictNullChecks` 设置为false，如果你要使用比较严格的语法呢就可以把它关闭掉，也可以设置 num 变量为联合类型这样就可以通过类型检查了

// void【在js中呢void是一种操作符它可以让任何表达式返回 undefined 】
let noReturn = () => {}

// any【在ts中如果我们不指定一个变量的类型那么它默认就是any类型，如果不是特殊情况我们不建议使用any类型因为如果我们把所有变量都定义成any就没有必要使用any了】
let x;
x = 1;
x = [];
x = () => {} // 我们可以给它任意的赋值


//never【表示永远不会有返回值的类型】
let error = ()=>{
  throw new Error('error'); // 一个函数抛出了异常这个函数就永远不会有返回值
}
let endless = ()=>{
  while (true) {} // 无限循环函数它永远都不会返回
}
